import type { IconifyIcon } from "@iconify/types";
import type { FunctionalComponent } from "vue";
import { Icon as OnlineIcon } from "@iconify/vue";
import { Icon as OfflineIcon } from "@iconify/vue/offline";
import { defineComponent, h } from "vue";

interface Props {
    icon: FunctionalComponent | IconifyIcon | string;
}

// Note[vue] Vue 3.3+ 支持在defineComponent中定义Props类型, 在 setup 和 render 函数中会自动类型推断
export default defineComponent<Props>({
    name: "IconifyIcon",
    props: {
        icon: {
            type: [Object, String],
            default: null,
        },
    },
    render() {
        const { VITE_IS_INTERNET } = import.meta.env;
        const attrs = this.$attrs;
        const props = {
            "aria-hidden": false,
            "style": attrs?.style
                ? Object.assign(attrs.style, { outline: "none" })
                : { outline: "none" },
            ...attrs,
        };
        if (typeof this.icon === "object") {
            // 本地引入的图标, 组件等
            return h(
                this.icon,
                props,
                {
                    default: () => [],
                },
            );
        } else if (typeof this.icon === "string") {
            if (VITE_IS_INTERNET === "false") {
                /**
                 * 离线使用（用于内网环境）, 在项目中主要用于动态的菜单图标
                 * 注意: 离线图标需要在项目入口处设置 setOfflineIcons() 方法, 代码位置: src/components/ReIcon/src/hooks.ts
                 */
                return h(
                    OfflineIcon,
                    {
                        icon: this.icon,
                        ...props,
                    },
                    {
                        default: () => [],
                    },
                );
            } else {
                // 在线使用（用于外网环境）
                return h(
                    OnlineIcon,
                    {
                        icon: this.icon,
                        ...props,
                    },
                    {
                        default: () => [],
                    },
                );
            }
        }
    },
});
